package com.ruoyi.project.system.label.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.deeplearning4j.models.word2vec.Word2Vec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.utils.Word2VecUtil;
import com.ruoyi.common.utils.ZipModel;
import com.ruoyi.common.utils.ZipUtil;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.system.label.domain.ExcelModel;
import com.ruoyi.project.system.label.domain.Label;
import com.ruoyi.project.system.label.service.ILabelService;
import com.ruoyi.project.system.picture.domain.Picture;
import com.ruoyi.project.system.picture.service.IPictureService;

@Controller
@RequestMapping("/system/label")
public class LabelController extends BaseController{
	@Autowired
	private ILabelService labelService;
	@Autowired
	private IPictureService pictureService;
	private String prefix = "system/label";
	
	@RequiresPermissions("system:label:view")
    @GetMapping()
    public String label()
    {
        return prefix + "/label";
    }
	
	@RequiresPermissions("system:label:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(Label label)
    {
        startPage();
        List<HashMap> list = labelService.selectLabelList(label);
        return getDataTable(list);
    }
	
	@RequiresPermissions("system:label:add")
	@PostMapping("/add")
	@Log(title = "标签管理", businessType = BusinessType.INSERT)
	@Transactional(rollbackFor = Exception.class)
	@ResponseBody
	public AjaxResult addSave(@RequestBody Label label){
		//需要合并的图片
		Picture picture = pictureService.selectPicture(label.getPictureId());
		//保存当前标签
		int rs = labelService.saveLabel(label);
		Label condition = new Label();
		System.out.println(label.getPictureId());
		condition.setPictureId(picture.getPictureId());
		//查询出需要合并图片的全部标签
		List<HashMap> labels =labelService.selectLabelList(condition);
		/**
		 * 只有两个标签且相等时直接采纳
		 * */
		if(labels.size()==2) {
			if(labels.get(0).get("picture_label").toString().equals(labels.get(1).get("picture_label").toString())) {
				picture.setUpdateBy(getLoginName());
				picture.setLabel(labels.get(0).get("picture_label").toString());
				pictureService.updatePicture(picture);
			}	
		}
		/**
		 * 两个以上标签计算互相的相似的，得出每个标签的平均相似度
		 * */
		else if(labels.size()>2)
		{
			/**
			 * similars[i][j]表示parms[i]与params[j]的相似度
			 * similars[i][i]表示parms[i]与其他词语的平均相似度
			 * */
			double[][] similars = new double[labels.size()][labels.size()]; 
			Word2Vec word2vec = Word2VecUtil.getWord2Vec();
			for(int i =0;i<labels.size();i++) {
				for(int j=i+1;j<labels.size();j++) {
					similars[j][i]=similars[i][j]=word2vec.similarity(labels.get(i).get("picture_label").toString(), labels.get(j).get("picture_label").toString());
				}
				for(int k=0;k<similars.length;k++)
					if(i!=k)
						similars[i][i]+=similars[i][k];
			}
			/**
			 * 取最高平均相似度的标签作为最终标签。保存到数据库
			 * 一般情况下平均相似度最高的标签能概况其他标签
			 * 如 小狗，狗，猫将会合并成狗。
			 * */
			int index=0;
			double max = 0.0;
		    for(int i=0;i<similars.length;i++) {
		    	if(similars[i][i]>max) {
		    		max = similars[i][i];
		    		index = i;
		    	}
		    }
		    picture.setUpdateBy(getLoginName());
			picture.setLabel(labels.get(index).get("picture_label").toString());
			pictureService.updatePicture(picture);
		}
		
		return toAjax(rs);
	}
	
	
	
    @GetMapping("/edit/{userId}/{pictureId}")
    public String edit(@PathVariable("userId")Long userId,@PathVariable("pictureId")Long pictureId,ModelMap mmap)
    {
    	mmap.put("label", labelService.selectLabel(userId, pictureId));
        return prefix + "/edit";
    }
    
    @RequiresPermissions("system:label:edit")
    @PostMapping("/edit")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "标签管理", businessType = BusinessType.UPDATE)
    @ResponseBody
    public AjaxResult editSave(Label label)
    {
    	return toAjax(labelService.updateLabel(label));
    }
	
	@RequiresPermissions("system:label:list")
	@GetMapping("/app/list")
	@ResponseBody
	public List<HashMap> list(){
		return labelService.selectByUser(getUser());
	}
	
	@Log(title = "标签管理", businessType = BusinessType.EXPORT)
	@RequiresPermissions("system:label:export")
	@RequestMapping("/exportData")
	public void exportData(HttpServletRequest request,HttpServletResponse response) throws Exception{
		List<ZipModel> zipModelList = new ArrayList<>();
		for(Picture picture :pictureService.selectPictureHasLabel()) {
			ZipModel zipModel = new ZipModel();
			zipModel.setFileName(picture.getFileName());
			zipModel.setFilePath(picture.getSrcPath());
			zipModelList.add(zipModel);
		}
    	String fileName = "result.zip";
    	String outFilePath = "C:\\"+ fileName;
    	File file = new File(outFilePath);
    	//文件输出流
    	FileOutputStream outStream = new FileOutputStream(file);
    	//压缩流
    	ZipOutputStream toClient = new ZipOutputStream(outStream);
    	//todo:调用通用方法下载fastfds文件，打包成zip文件
    	ZipUtil.zipFile(zipModelList, toClient);
    	toClient.close();
    	outStream.close();
    	response.setHeader("content-disposition", "attachment;fileName=" + fileName);
    	//todo:将zip文件下载下来
    	ZipUtil.downloadZip(file, response);
	}
	
    @Log(title = "标签管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("system:label:export")
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export() throws Exception
    {
        try
        {
            List<Picture> list = pictureService.selectPictureHasLabel();
            ExcelUtil<Picture> util = new ExcelUtil<Picture>(Picture.class);
            return util.exportExcel(list, "excelmodel");
        }
        catch (Exception e)
        {
        	e.printStackTrace();
            return error("导出Excel失败，请联系网站管理员！");
        }
    }
	
	
	/**
	 * Word2VecTest
	 * */
	@GetMapping("/test")
	public String word2vecTest(){
		return prefix+"/test";
	}
	@PostMapping("/similar")
	public String similar(String words) {
		/**
		 * similars[i][j]表示parms[i]与params[j]的相似度
		 * similars[i][i]表示parms[i]与其他词语的平均相似度
		 * */
		String[] parms = words.split(",");
		
		double[][] similars = new double[parms.length][parms.length]; 
		Word2Vec word2vec = Word2VecUtil.getWord2Vec();
		for(int i =0;i<parms.length;i++) {
			for(int j=i+1;j<parms.length;j++) {
				similars[j][i]=similars[i][j]=word2vec.similarity(parms[i], parms[j]);
			}
			for(int k=0;k<similars.length;k++)
				if(i!=k)
					similars[i][i]+=similars[i][k];
		}
		
		int index=0;
		double max = 0.0;
	    for(int i=0;i<similars.length;i++) {
	    	if(similars[i][i]>max) {
	    		max = similars[i][i];
	    		index = i;
	    	}
	    }
	    System.out.println(parms[index]);

		return prefix+"/test";
	}
	
	
}
